package org.dingyom.car.service.impl;

import org.apache.commons.lang3.StringUtils;
import org.dingyom.basics.util.PageList;
import org.dingyom.car.es.doc.CarDoc;
import org.dingyom.car.es.repository.CarDocRepository;
import org.dingyom.car.query.CarSearchQuery;
import org.dingyom.car.service.ICarSearchService;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
@Service
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)//查询 只读
public class CarSearchServiceImpl implements ICarSearchService {
    @Autowired
    private CarDocRepository repository;

    /**
     * 高级查询 query bool must/filter
     * 排序 sort
     * 分页 from size
     * @param query
     * @return
     */
    @Override
    public PageList<CarDoc> search(CarSearchQuery query) {
        //dsl
        /*1 本地查询生成器*/
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        /*2 高级查询条件*/
        //查询 keyword--titl，shopName，typeName，carInfo
        String keyword = query.getKeyword();
        if(StringUtils.isNotBlank(keyword)){//lang3包中的工具类
            boolQuery.must(QueryBuilders.multiMatchQuery(keyword.trim(),
                    "title","shopName","typeName","carInfo"));
        }
        //过滤 filters存放过滤条件
        List<QueryBuilder> filters = boolQuery.filter();
        //添加过滤条件
        Integer costeffective = query.getCosteffective();
        Integer rushsale = query.getRushsale();
        Integer quasinewcar = query.getQuasinewcar();
        Integer transitivecountry = query.getTransitivecountry();
        Long carType = query.getCarType();
        if (costeffective!=null)
            filters.add(QueryBuilders.termQuery("costeffective",costeffective));
        if (rushsale!=null)
            filters.add(QueryBuilders.termQuery("rushsale",rushsale));
        if (quasinewcar!=null)
            filters.add(QueryBuilders.termQuery("quasinewcar",quasinewcar));
        if (transitivecountry!=null)
            filters.add(QueryBuilders.termQuery("transitivecountry",transitivecountry));
        if (carType!=null)
            filters.add(QueryBuilders.termQuery("typeId",carType));
        Integer carAge = query.getCarAge();//车龄
        Integer carAgeType = query.getCarAgeType();//车龄类型 0以下，1以上
        if(carAgeType!=null&&carAge!=null){
            //当前时间-车龄 就是车辆注册时间
            Date date = new Date(new Date().getTime() - carAge * 365 * 24 * 60 * 60 * 1000);
            if (carAgeType.intValue()==0) //以下
            {
                //reigstertime+五年时间>=当前时间 不能以reigstertime为主 因为是未知的 这个就是我们要去查的
                //reigstertime>=当前时间-五年时间
                filters.add(QueryBuilders.rangeQuery("reigstertime").gte(date));
            }else{ //以上
                //reigstertime+五年时间<=当前时间 不能以reigstertime为主 因为是未知的 这个就是我们要去查的
                //reigstertime<=当前时间-五年时间
                filters.add(QueryBuilders.rangeQuery("reigstertime").lte(date));
            }
        }
        //最小价格
        BigDecimal priceMin = query.getPriceMin();
        if (priceMin != null) {
            filters.add(QueryBuilders.rangeQuery("costprice").gte(priceMin));
        }
        //最大价格
        BigDecimal priceMax = query.getPriceMax();
        if (priceMax != null) {
            filters.add(QueryBuilders.rangeQuery("costprice").lte(priceMax));
        }

        builder.withQuery(boolQuery);//这里才正式条件查询

        /*3 排序--对查询的内容进行排序*/
        String orderType = query.getOrderType();//排序类型 asc 升序，desc 降序
        String orderField = query.getOrderField();//价格 jg，车龄 cl，里程 lc，最新上架时间 no
        orderField = orderField==null?"jg":orderField; //默认价格排序
        //排序方式处理
        SortOrder sortOrder = SortOrder.DESC;//默认降序排列
        if ("asc".equals(orderType))
            sortOrder = SortOrder.ASC;

        if ("jg".equals(orderField)){//价格
            builder.withSort(SortBuilders.fieldSort("costprice").order(sortOrder));
        }
        if ("cl".equals(orderField)){//车龄
            builder.withSort(SortBuilders.fieldSort("reigstertime").order(sortOrder));
        }
        if ("lc".equals(orderField)){//里程
            builder.withSort(SortBuilders.fieldSort("mileage").order(sortOrder));
        }
        if ("no".equals(orderField)){//最新上架时间
            builder.withSort(SortBuilders.fieldSort("onsaletime").order(sortOrder));
        }

        /*4 分页 先排序再分页
        * 页数，和每页的size*/
        //builder.withPageable(PageRequest.of(query.getStart(), query.getPageSize()));
        builder.withPageable(PageRequest.of(query.getCurrentPage()-1, query.getPageSize()));

        /*5 封装数据*/
        Page<CarDoc> carDocs = repository.search(builder.build());

        long total = carDocs.getTotalElements();//查询的总数
        List<CarDoc> rows = carDocs.getContent();//具体数据
        Long totalPage = 1L;//总页数 默认是1
        if (total>Long.valueOf(query.getPageSize())) {
            totalPage = total / Long.valueOf(query.getPageSize()) + 1L;
        }
        return new PageList<>(total,rows,totalPage);
    }
}
